package com.himiotech.core.framework.config.mvc;

import com.himiotech.core.framework.helper.exception.DemoException;
import com.himiotech.core.framework.helper.exception.HimioException;
import com.himiotech.core.framework.helper.utils.ServletUtils;
import com.himiotech.core.project.web.base.model.HimioResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.AuthorizationException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;

/**
 * 全局异常处理器
 *
 * @author ruoyi
 * @author wuwenbin
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 权限校验失败 如果请求为ajax返回json，普通请求跳转页面
     */
    @ExceptionHandler(AuthorizationException.class)
    public Object handleAuthorizationException(HttpServletRequest request, AuthorizationException e) {
        log.error(e.getMessage(), e);
        if (ServletUtils.isAjaxRequest(request)) {
            return HimioResult.errMsg(e.getMessage());
        } else {
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.setViewName("error/403");
            return modelAndView;
        }
    }

    /**
     * 请求方式不支持
     */
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public HimioResult handleException(HttpRequestMethodNotSupportedException e) {
        log.error(e.getMessage(), e);
        return HimioResult.errMsgFormat("不支持'{}'请求", e.getMessage());
    }

    /**
     * 拦截未知的运行时异常
     */
    @ExceptionHandler(RuntimeException.class)
    public Object notFount(HttpServletRequest request, RuntimeException e) {
        log.error("运行时异常:", e);
        if (ServletUtils.isAjaxRequest(request)) {
            return HimioResult.errMsgFormat("运行时异常:{}", e.getMessage());
        } else {
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.addObject("errorMessage", e.getMessage());
            modelAndView.setViewName("error/500");
            return modelAndView;
        }
    }


    /**
     * 异常
     */
    @ExceptionHandler({HimioException.class, Exception.class})
    public Object businessException(HttpServletRequest request, HimioException e) {
        log.error(e.getMessage(), e);
        if (ServletUtils.isAjaxRequest(request)) {
            return HimioResult.errMsg(e.getMessage());
        } else {
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.addObject("errorMessage", e.getMessage());
            modelAndView.setViewName("error/500");
            return modelAndView;
        }
    }


    /**
     * 自定义验证异常
     */
    @ExceptionHandler(BindException.class)
    public HimioResult validatedBindException(BindException e) {
        log.error(e.getMessage(), e);
        String message = e.getAllErrors().get(0).getDefaultMessage();
        return HimioResult.errMsg(message);
    }

    /**
     * 演示模式拦截
     *
     * @param e
     * @return
     */
    @ExceptionHandler(DemoException.class)
    public HimioResult demoValidate(DemoException e) {
        log.error(e.getMessage(), e);
        return HimioResult.errMsg(e.getMessage());
    }
}
